/*-
 * RP_MO_DATA.java     v2.0  19-Dec-2004
 *
 * $LastChangedBy: stein $
 * $LastChangedRevision: 96 $
 * $LastChangedDate: 2007-02-15 19:53:47 +0000 (Thu, 15 Feb 2007) $
 * $HeadURL: svn://localhost/SMS/src/net/sourceforge/attention/smrl/RP_MO_DATA.java $
 *
 * Copyright (c) 2007, Stein Gunnar Bakkeby
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Stein Gunnar Bakkeby nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.googlecode.attention.smrl;

import com.googlecode.attention.sms.pdu.Address;
import com.googlecode.attention.sms.pdu.MTI;
import com.googlecode.attention.sms.pdu.SMSCommand;
import com.googlecode.attention.sms.pdu.SMSDeliverReport;
import com.googlecode.attention.sms.pdu.SMSSubmit;
import com.googlecode.attention.sms.pdu.TOA;
import com.googlecode.attention.sms.pdu.TPDU;
import com.googlecode.attention.util.Convert;


/** * RP-MO-DATA. * <BR> * <BR>Basic elements of the RP-MO-DATA type. * <BR> * <BR>Used for: * <BR> - SMS-DELIVER-REPORT * <BR> - SMS-SUBMIT * <BR> - SMS-COMMAND * <BR> * <BR> * <TABLE BORDER="1"> * <TR><TD>Abbr.</TD><TD>Reference</TD><TD>P1)</TD><TD>Description</TD></TR> * <TR><TD>RP-OA</TD><TD>RP-Originating-Address</TD><TD>++-</TD><TD>Address of the originating MS.</TD></TR> * <TR><TD>RP-DA</TD><TD>RP-Destination-Address</TD><TD>-++</TD><TD>Address of the destination SC.</TD></TR> * <TR><TD>RP-UD</TD><TD>RP-User-Data</TD><TD>+++</TD><TD>Parameter containing the TPDU</TD></TR> * </TABLE> * <BR> * <BR>1) Provision on the links SC<->MSC, MSC<->MSC or MSC<->SGSN, *     and MSC<->MS or SGSN<->MS indicated by "xxx", where x may be either *     "+" or "-", dependent on whether the parameter is mandatory or not on *     the respective link. *  * @author Stein Gunnar Bakkeby */
public class RP_MO_DATA {

  /* Field values */
  private Address oa = null;
  private Address da = null;
  private TPDU data = null;

  /** Default link. */
  public static int       DEFAULT      = 1;
  /** The link between SC and MSC. */
  public static final int SC_AND_MSC   = 0;
  /** The link between MSCs. */
  public static final int MSC_AND_MSC  = 1;
  /** The link between SGSN and MSC. */
  public static final int MSC_AND_SGSN = 1;
  /** The link between MS and MSC. */
  public static final int MSC_AND_MS   = 2;
  /** The link between SGSN and MS. */
  public static final int SGSN_AND_MS  = 2;
  
  /**
   * Default constructor, creates an empty RP-MO-DATA.
   */
  public RP_MO_DATA() {
  }
  
  /**
   * Constructor, this will create the RP-MO-DATA.
   * 
   * @param oa Originating Address
   * @param da Destination Address
   * @param rpdu The RP-UD
   */
  public RP_MO_DATA(final Address oa,
                    final Address da,
                    final SMSSubmit rpdu) {
    this.oa = oa;
    this.da = da;
    this.data = rpdu;
  }
  
  /**
   * Constructor, this will create the RP-MO-DATA.
   * 
   * @param oa Originating Address
   * @param da Destination Address
   * @param rpdu The RP-UD
   */
  public RP_MO_DATA(final Address oa,
                    final Address da,
                    final SMSCommand rpdu) {
    this.oa = oa;
    this.da = da;
    this.data = rpdu;
  }
  
  /**
   * Constructor, this will create the RP-MO-DATA.
   * 
   * @param oa Originating Address
   * @param da Destination Address
   * @param rpdu The RP-UD
   */
  public RP_MO_DATA(final Address oa,
                    final Address da,
                    final SMSDeliverReport rpdu) {
    this.oa = oa;
    this.da = da;
    this.data = rpdu;
  }
  
  /**
   * Constructor, this will decode the raw data using the default link.
   * 
   * @param octets The raw data
   * @param hasSMSCInfo Indicates whether SMSC info is present in received PDU
   * @throws IllegalArgumentException If not RP-MO-DATA
   * @see #DEFAULT
   * @see #RP_MO_DATA(String, int)
   */
  public RP_MO_DATA(final String octets,
      final boolean hasSMSCInfo) throws IllegalArgumentException {
    this(octets, DEFAULT, hasSMSCInfo);
  }
  
  /**
   * Constructor, this will decode the raw data.
   * 
   * @param octets The raw data of the RP-MO.
   * @param link See static field values
   * @param hasSMSCInfo Indicates whether SMSC info is present in received PDU
   * @throws IllegalArgumentException If not RP-MO-DATA
   */
  public RP_MO_DATA(final String octets, final int link,
                    final boolean hasSMSCInfo)
  throws IllegalArgumentException {
    try {
      int index  = 0;
      int index2 = 0;
      switch (link) {
      default:
      case MSC_AND_MSC: // MSC_AND_SGSN
      case SC_AND_MSC:
        /* Originating Address */
        String oal    = octets.substring(0, 2);
        String oa_toa = octets.substring(2, 4);
        index         = 4 + Convert.hexToInt(oal);
        String oa     = octets.substring(4, index);
        this.oa = new Address(Convert.hexToInt(oal), new TOA(oa_toa), Convert.hexToIntArray(oa, 2));
        if (link == SC_AND_MSC) break;
        /* else: falls through */
        
      case MSC_AND_MS:  // SGSN_AND_MS (Originating Address not mandatory)
        /* Destination Address */
        String dal    = octets.substring(index, index + 2);
        String da_toa = octets.substring(index + 2, index + 4);
        index        += 4;
        index2        = index + Convert.hexToInt(dal);
        String da     = octets.substring(index, index2);
        this.oa = new Address(Convert.hexToInt(dal), new TOA(da_toa), Convert.hexToIntArray(da, 2));
        break;
      }
      /* TPDU */
      data = TPDU.getPDU(octets.substring(index2),
                         MTI.DIRECTION.MS_TO_SC, false, hasSMSCInfo);
    } catch (Exception e) {
      throw new IllegalArgumentException(octets);
    }
  }
  
  /* Get methods */
  /**
   * This will return the originating address, or null if not present.
   * 
   * @return The RP-OA
   */
  public Address getOriginatingAddress() {
    return oa;
  }
  
  /**
   * This will return the destination address, or null if not present.
   * 
   * @return The RP-DA
   */
  public Address getDestinationAddress() {
    return da;
  }
  
  /**
   * This will return the TPDU.
   * 
   * @return The RP-UD
   */
  public TPDU getTPDU() {
    return data;
  }
  
  /**
   * This will return the raw data of this RP-MO-DATA using the default link.
   * 
   * @return The raw data
   * @see #DEFAULT
   * @see #getOctets(int)
   */
  public String getOctets() {
    return getOctets(DEFAULT);
  }
  
  /**
   * This will return the raw data of this RP-MO-DATA.
   * 
   * @param link See static field values
   * @return The raw data
   */
  public String getOctets(final int link) {
    /* Avoid NullPointerException */
    if (oa == null) oa = new Address();
    if (da == null) da = new Address();
    if (data == null) data = new SMSSubmit();
    
    String output = "";
    switch (link) {
    default:
    case MSC_AND_MSC: // MSC_AND_SGSN
    case SC_AND_MSC:
      /* Originating Address */
      output += oa.getAddressField();
      if (link == SC_AND_MSC) break;
      /* else: falls through */
      
    case MSC_AND_MS:  // SGSN_AND_MS (Originating Address not mandatory)
      /* Destination Address */
      output += da.getAddressField();
      break;
    }
    /* TPDU */
    return output + data.getPDU();
  }
  
  /* Set methods */
  /**
   * This will set the originating address.
   * 
   * @param oa The RP-OA
   */
  public void setOriginatingAddress(final Address oa) {
    this.oa = oa;
  }
  
  /**
   * This will set the destination address.
   * 
   * @param da The RP-DA
   */
  public void setDestinationAddress(final Address da) {
    this.da = da;
  }
  
  /**
   * This will set the TPDU.
   * 
   * @param tpdu The RP-UD
   */
  public void setTPDU(final SMSSubmit tpdu) {
    this.data = tpdu;
  }
  
  /**
   * This will set the TPDU.
   * 
   * @param tpdu The RP-UD
   */
  public void setTPDU(final SMSCommand tpdu) {
    this.data = tpdu;
  }
  
  /**
   * This will set the TPDU.
   * 
   * @param tpdu The RP-UD
   */
  public void setTPDU(final SMSDeliverReport tpdu) {
    this.data = tpdu;
  }
}